package com.woniuxy.cloud.carl.carlstation.app.apiImpl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.cloud.Aspect.log.Log;
import com.woniuxy.cloud.carl.carlstation.app.util.JwtUtil;
import com.woniuxy.cloud.carl.carlstation.client.StaffClient;
import com.woniuxy.cloud.carl.carlstation.client.dto.StaffDto;
import com.woniuxy.cloud.carl.carlstation.client.param.AddStaffParam;
import com.woniuxy.cloud.carl.carlstation.client.param.FindStaffByConditionParam;
import com.woniuxy.cloud.carl.carlstation.client.param.ManagerPhoneLoginParam;
import com.woniuxy.cloud.carl.carlstation.client.param.ModifyStaffParam;
import com.woniuxy.cloud.carl.carlstation.common.CarlstationResultCode;
import com.woniuxy.cloud.carl.carlstation.common.RedisKey;
import com.woniuxy.cloud.carl.carlstation.infra.mapper.StaffMapper;
import com.woniuxy.cloud.carl.carlstation.infra.mapper.StationMapper;
import com.woniuxy.cloud.carl.carlstation.infra.model.Staff;
import com.woniuxy.cloud.carl.carlstation.infra.model.Station;
import com.woniuxy.cloud.carl.carlstation.service.StaffService;
import com.woniuxy.cloud.carl.carlstation.service.dto.StaffServiceDto;
import com.woniuxy.cloud.carl.carlstation.service.param.LoginServiceParam;
import com.woniuxy.cloud.carl.store.client.StoreClient;
import com.woniuxy.cloud.carl.store.client.param.GetStoreParam;
import com.woniuxy.cloud.carl.store.client.result.StoreDto;
import com.woniuxy.cloud.carl.store.infra.mapper.StoreMapper;
import com.woniuxy.cloud.carl.store.infra.model.Store;
import com.woniuxy.cloud.carl.store.infra.model.StoreService;
import com.woniuxy.exceptions.MallException;
import com.woniuxy.result.Result;
import com.woniuxy.utils.Assert;
import com.woniuxy.utils.MyPage;
import io.seata.core.protocol.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.StoreManager;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@CrossOrigin("*")
public class StaffImpl implements StaffClient {
    @Resource
    private StaffService staffService;

    @Resource
    private StationMapper stationMapper;
    @Resource
    private StaffMapper staffMapper;
    @Resource
    private StoreClient storeClient;
    @Resource
    private RedissonClient redissonClient;

    @Override
    public Result addStaff(AddStaffParam param) {
        String managerPhone = param.getPhone();
        QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", managerPhone);
        Staff isStaff = staffMapper.selectOne(queryWrapper);
        if(isStaff!=null){
            throw new MallException(CarlstationResultCode.MANAGER_IS_EXIST);
        }
        Long stationId = param.getStationId();
        Station station = stationMapper.selectById(stationId);
        Assert.state(station != null, "暂无该岗位");
        if(param.getStoreId()!=0) {
            //注册管理员默认门店id为0 不参与验证门店信息
            Long storeId = param.getStoreId();//TODO   检验门店是否存在
            GetStoreParam getStoreParam = new GetStoreParam();
            getStoreParam.setStoreId(storeId);
            Result<List<StoreDto>> storer = storeClient.getStore(getStoreParam);
            List<StoreDto> store = storer.getData();
            Assert.state(store!=null||store.size()!= 0, "暂无该门店");
        }
        Staff staff = BeanUtil.toBean(param, Staff.class);
        staff.setStationName(station.getStationName());
        staff.setReceptionCount(0);
        staff.setEnterTime(new Date());
        staff.setStaffScore(5.0);
        staff.setState(2);
        staffMapper.insert(staff);
        return Result.success();
    }
@Log("根据条件查询员工")
    @Override
    public Result<MyPage<StaffDto>> findStaffByCondition(FindStaffByConditionParam param) {
    MyPage<StaffServiceDto> staffByCondition = staffService.findStaffByCondition(param.getPageNum(), param.getPageSize(), param.getCondition());
    return Result.success(staffByCondition);
    }

    @Override
    public Result<List<StaffDto>> findStaffsByStoreId(Long storeId) {
        QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("store_id",storeId);
        List<Staff> list = staffMapper.selectList(queryWrapper);
        return Result.success(list);
    }

    @Override
    public Result<StaffDto> findStaffById(Long staffId) {
        Staff staff = staffMapper.selectById(staffId);
//        if(1==1){
//            throw new MallException(CarlstationResultCode.CODE_ILLEGAL);
//        }
        Assert.state(staff!=null,"该员工不存在");
        StaffDto staffDto = BeanUtil.toBean(staff, StaffDto.class);

        return Result.success(staffDto);
    }

    @Override
    public Result modifyStaff(ModifyStaffParam param) {
        if(param.getStoreId()!=null){
            Long storeId = param.getStoreId();
            GetStoreParam getStoreParam = new GetStoreParam();
            getStoreParam.setStoreId(storeId);
            Result<List<StoreDto>> storer = storeClient.getStore(getStoreParam);
            List<StoreDto> store = storer.getData();
            Assert.state(store!=null||store.size()!= 0, "暂无该门店");
        }
        Staff staff = BeanUtil.toBean(param, Staff.class);
        if(param.getStationId()!=null){
            Long stationId = param.getStationId();
            Station station = stationMapper.selectById(stationId);
            Assert.state(station != null, "暂无该岗位");
            staff.setStationName(station.getStationName());
        }



     staffMapper.updateById(staff);
        return Result.success();
    }

    @Override
    public Result<String> managerLogin(ManagerPhoneLoginParam param) {

        //判断账号存在
        Staff staff = staffService.getOne(new QueryWrapper<Staff>().eq("phone", param.getPhone()));

        if(staff==null) throw new MallException(CarlstationResultCode.MANAGER_NOT_EXIST);
        if(staff.getStationId()!=1&&staff.getStationId()!=2){
            throw new MallException(CarlstationResultCode.MANAGER_NOT_EXIST);
        }
        //判断redis中存Key
        RMapCache<String, String> map = redissonClient.getMapCache(RedisKey.MANAGER_LOGIN_CODE);
        if(!map.containsKey(param.getPhone())) throw new MallException(CarlstationResultCode.CODE_ILLEGAL);
        //判断验证码
        String code = map.get(param.getPhone());
        if(code==null) throw new MallException(CarlstationResultCode.CODE_ILLEGAL);
        if(!code.equals(param.getCode())) throw new MallException(CarlstationResultCode.CODE_ILLEGAL);

        LoginServiceParam serviceParam = BeanUtil.toBean(param, LoginServiceParam.class);
        String managerPhone = serviceParam.getPhone();
        //TODO 管理员才能登录
        Staff staff1 = staffService.checkStaffByPhone(managerPhone);
        Long userId = staff1.getStaffId();
        Long stationId = staff1.getStationId();
        HashMap<String, Object> body = new HashMap<>();
        body.put("sub",userId);
        if(stationId==2){//普通管理员
            body.put("role",3);
        }else if (stationId==1){
            //超级管理员
            body.put("role",4);
        }

        Integer minites = 300;
        String accessToken = JwtUtil.createToken(body,minites);
        return Result.success(accessToken);

    }

    @Override
    public Result sendLoginCode(String managerPhone) {
        if(managerPhone==null||managerPhone.equals("")){
            throw new MallException(CarlstationResultCode.PHONE_NOT_EXIST);
        }
        QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", managerPhone);
        Staff staff = staffMapper.selectOne(queryWrapper);
        if (staff == null) {
            throw new MallException(CarlstationResultCode.MANAGER_NOT_EXIST);
        }
        if(staff.getStationId()!=1&&staff.getStationId()!=2){
            throw new MallException(CarlstationResultCode.MANAGER_NOT_EXIST);
        }
        //判断一分钟内是否已经发过
        RMapCache<String, String> LoginInMap = redissonClient.getMapCache(RedisKey.LOGIN_CODE_IN_MIN);
        if(LoginInMap.containsKey(managerPhone)) throw new MallException(CarlstationResultCode.CODE_USE_TO_MUCH);
        //判断一小时内是否已经第五次了
        RMapCache<String, Integer> map = redissonClient.getMapCache(RedisKey.LOGIN_CODE_IN_HOURS);
        if(map.containsKey(managerPhone)){
            Integer time = map.get(managerPhone);
            if(time==5) throw new MallException(CarlstationResultCode.ACCOUNT_CODE_MUCH_5);
        }
//        String code = SMSUtil.send(phone);
        //存入五分钟的code
        String code = "123456";
        RMapCache<String, String> RegMap = redissonClient.getMapCache(RedisKey.MANAGER_LOGIN_CODE);
        RegMap.put(managerPhone,code,300, TimeUnit.SECONDS);
        //一分钟内只能发一次
        RMapCache<String, String> mapInMin = redissonClient.getMapCache(RedisKey.LOGIN_CODE_IN_MIN);
        mapInMin.put(managerPhone,managerPhone,60,TimeUnit.SECONDS);
        //一个小时只能发5次
        RMapCache<String, Integer> mapInHour = redissonClient.getMapCache(RedisKey.LOGIN_CODE_IN_HOURS);
        if(!mapInHour.containsKey(managerPhone)){
            mapInHour.put(managerPhone,0,1,TimeUnit.HOURS);
        }
        mapInHour.put(managerPhone,map.get(managerPhone)+1);
        return Result.success(code);

    }


}
